AVL树总结



AVL树总结

AVL树是二叉查找树的一种优化,能将链状的二叉查找树几乎平均地储存下来,从而减少搜索使用的时间。

 

AVL树是空树,或满足以下定义的树:

1、左右子树都是AVL树;(递归定义)

2、左右子树高度之差不超过1

 

定义平衡因子:

左子树高度-右子树高度,当平衡因子大于等于2时,我们就称这棵树不平衡,需要通过旋转让它重新平衡。

 

获取节点高度:

       int h(int rt){

       if(rt==0) return -1;//这里return-1的原因后面阐释

       return no[rt].height;

}

 

单旋转

“左左当根节点的左子树的左儿子与根节点的右儿子不平衡时

我们通过单旋转使平衡树符合该树的性质

int SingeRotateWithLeft(int x){
	int y;
	y=no[x].left;
	no[x].left=no[y].right;
	no[y].right=x;
	no[y].height=max(h(no[y].left),h(no[y].right))+1;
	no[x].height=max(h(no[x].left),h(no[x].right))+1;
	return y;
}

“右右方法类似,与左左对称

 

双旋转

“左右当根节点的左子树的右儿子与根节点的右儿子不平衡时

旋转两次即可使这棵树平衡

int doubleRotateWithLeft(int x){

	no[x].left=SingleRotateWithRight(no[x].left);
	return SingleRotateWithLeft(x);

}

“右左同理。

 

插入操作:先正常插入指定结点,再判断原树是否平衡,不平衡要根据具体情况旋转使原树平衡

int insert(int k,int rt){
	if(rt==0)
		rt=newNode(k);
	else if( k< no[rt].key ){
		no[rt].left=insert(k,no[rt].left);
		if( h(no[rt].left)-h(no[rt].right) )==2 )
			if(k<no[ no[rt].left ] .key ) rt=SingleRotateWithLeft(rt);
			else rt= DoubleRotateWithLeft(rt)
	}else if( k > no[rt].key){
		no[rt].right=insert(k,no[rt].right);
		if( h(no[rt].right)-h(no[rt].left) )==2 )
			if(k > no[ no[rt].right ] .key ) rt=SingleRotateWithRight(rt);
			else rt= DoubleRotateWithRight(rt)
	}
	no[rt].height = max ( h( no[rt].left ), h( no[rt].right ) ) +1;
	return rt;
}

int newNode(int k){
	no[cnt].height=no[cnt].left=no[cnt].right=0;
	no[cnt].key=k;
	return cnt++;
}

 AVL树过于复杂,但却是其他二叉搜索树变形特别是旋转的基础,删除操作实在过于复杂,本人无法理解。。。建议大家使用懒惰标记吧,不在真正意义上删除结点。

说这么多 大家还是转战SBT吧QAQ

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值